home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / uucp.cq / uucp.c
Text File  |  1985-04-27  |  18KB  |  841 lines

  1. /* @(#)uucp.c    1.9 */
  2. #include "uucp.h"
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include "uust.h"
  6. #include <sys/param.h>
  7.  
  8.  
  9. /*
  10.  * uucp
  11.  * user id 
  12.  * make a copy in spool directory
  13.  */
  14. int Uid;
  15. int Copy = 0;
  16. char Nuser[32];
  17. char *Ropt = " ";
  18. char Path[MAXFULLNAME], Optns[10], Ename[NAMEBUF];
  19. char Grade = 'n';
  20.  
  21. #define MAXCOUNT 20    /* maximun number of commands per C. file */
  22.  
  23. char    Sfile[MAXFULLNAME];
  24. #define JOBON    1
  25. #define JOBOFF    0
  26. #ifdef ONJOB
  27. int    prjob = JOBON;
  28. #else
  29. int    prjob    = JOBOFF;
  30. #endif
  31. char    **Env;
  32. int    notifopt;
  33. long ulimit();
  34. main(argc, argv, envp)
  35. char *argv[];
  36. char    **envp;
  37. {
  38.     int ret;
  39.     int errors = 0;
  40.     char *sysfile1, *sysfile2, *cp;
  41.     char file1[MAXFULLNAME], file2[MAXFULLNAME];
  42.     long limit, dummy;
  43.     char msg[100];
  44. #ifdef FOWARD
  45.     char tsys2[MAXFULLNAME];
  46.     char tfile1[MAXFULLNAME];
  47.     char sys2save[MAXFULLNAME];
  48. #endif
  49.     char    sqn[5];
  50.     char *strchr(), *strcpy(), *strcat();
  51.     char *strrchr();
  52.     char    *ep;
  53.     char    *fopt;
  54.  
  55.     fopt = NULL;
  56.     Env = envp;
  57.     if((ep = (char *)getenv("JOBNO="))){
  58.         if(strcmp("ON", ep) == SAME)
  59.             prjob = JOBON;
  60.         if(strcmp("OFF", ep) == SAME)
  61.             prjob = JOBOFF;
  62.     }
  63.     strcpy(Progname, "uucp");
  64.     Pchar = 'U';
  65.  
  66.     /*
  67.      * find name of local system
  68.      */
  69.     uucpname(Myname);
  70.     umask(WFMASK);
  71.     Optns[0] = '-';
  72.     Optns[1] = 'd';
  73.     Optns[2] = 'c';
  74.     Ename[0] = Nuser[0] = Optns[3] = '\0';
  75.     Sfile[0] = '\0';
  76.     while(argc>1 && argv[1][0] == '-'){
  77.         switch(argv[1][1]){
  78.  
  79.         /*
  80.          * make a copy of the file in the spool
  81.          * directory.
  82.          */
  83.         case 'C':
  84.             Copy = 1;
  85.             Optns[2] = 'C';
  86.             break;
  87.  
  88.         /*
  89.          * not used
  90.          */
  91.         case 'c':
  92.             break;
  93.  
  94.         /*
  95.          * not used
  96.          */
  97.         case 'd':
  98.             break;
  99.         case 'f':
  100.             Optns[1] = 'f';
  101.             break;
  102.  
  103.         /*
  104.          * invok uux to execute command
  105.          */
  106.         case 'e':
  107. #ifdef FOWARD
  108.             sprintf(Ename, "%s", &argv[1][2]);
  109. #else
  110.             sprintf(Ename, "%.6s", &argv[1][2]);
  111. #endif
  112.             break;
  113.  
  114.         /*
  115.          * set service grade (not used)
  116.          */
  117.         case 'g':
  118.             Grade = argv[1][2]; 
  119.             break;
  120.         case 'j':
  121.             prjob = (prjob == JOBON)?JOBOFF:JOBON;
  122.             break;
  123.  
  124.         /*
  125.          * send notification to local user
  126.          */
  127.         case 'm':
  128.             strcat(Optns, "m");
  129.             if(argv[1][2] != '\0'){
  130.                 fopt = &argv[1][2];
  131.                 strcat(Optns, "o");
  132.             }
  133.             break;
  134.  
  135.         /*
  136.          * send notification to user on remote
  137.          * if no user specified do not send notification
  138.          */
  139.         case 'n':
  140.             notifopt++;
  141.             sprintf(Nuser, "%.8s", &argv[1][2]);
  142.             break;
  143.  
  144.         /*
  145.          * create JCL files but not start uucico
  146.          */
  147.         case 'r':
  148.             Ropt = argv[1];
  149.             break;
  150.         case 's':
  151.             Spool = &argv[1][2]; 
  152.             break;
  153.  
  154.         /*
  155.          * turn on debugging
  156.          */
  157.         case 'x':
  158.             Debug = atoi(&argv[1][2]);
  159.             if (Debug <= 0)
  160.                 Debug = 1;
  161.             break;
  162.         default:
  163.             printf("unknown flag %s\n", argv[1]); 
  164.             break;
  165.         }
  166.         --argc;  argv++;
  167.     }
  168.     DEBUG(4, "\n\n** %s **\n", "START");
  169.     gwd(Wrkdir);
  170.     if(fopt){
  171.         if(*fopt != '/')
  172.             sprintf(Sfile, "%s/%s", Wrkdir, fopt);
  173.         else
  174.             sprintf(Sfile, "%s", fopt);
  175.  
  176.     }
  177.     /*
  178.      * work in spool directory
  179.      */
  180.     ret = chdir(Spool);
  181.     ASSERT(ret == 0, "CANNOT CHDIR TO SPOOL - ", Spool, ret);
  182.     if(ret != 0) {
  183.         fprintf(stderr, "No spool directory - %s - get help\n", Spool);
  184.         cleanup(-2);
  185.     }
  186.  
  187.     Uid = getuid();
  188.  
  189.     /*
  190.      * find id of user who spawned command to 
  191.      * determine
  192.      */
  193.     ret = guinfo(Uid, User, Path);
  194.     if(Nuser[0] == '\0')
  195.         strcpy(Nuser, User);
  196.     ASSERT(ret == 0, "CAN NOT FIND UID", "", Uid);
  197.     strcpy(Loginuser,User);
  198.     DEBUG(4, "UID %d, ", Uid);
  199.     DEBUG(4, "User %s,", User);
  200.     DEBUG(4, "Ename (%s) ", Ename);
  201.     DEBUG(4, "PATH %s\n", Path);
  202.     if (argc < 3) {
  203.         fprintf(stderr, "usage uucp from ... to\n");
  204.         cleanup(-3);
  205.     }
  206.  
  207.  
  208.     /*
  209.      * set up "to" system and file names
  210.      */
  211.     if ((cp = strchr(argv[argc - 1], '!')) != NULL) {
  212.         sysfile2 = argv[argc - 1];
  213.         *cp = '\0';
  214.         if (*sysfile2 == '\0')
  215.             sysfile2 = Myname;
  216.         else
  217.             sprintf(Rmtname, "%.6s", sysfile2);
  218.         if (versys(sysfile2) != 0) {
  219.             fprintf(stderr, "bad system name: %s\n", sysfile2);
  220.             cleanup(-4);
  221.         }
  222.         strcpy(file2, cp + 1);
  223. #ifdef FOWARD
  224.  
  225.         /*
  226.          * Fowarding
  227.          */
  228.         if ( strchr(file2, '!') != NULL && file2[0] != '~' ) {
  229.             if (chkpub(file2)==FAIL) {
  230.                 fprintf(stderr,"\n Forwarding to nonpublic directories denied - uucp failed\n");
  231.                 cleanup(-5);
  232.             }
  233.             *cp = '!';
  234.             strcpy(file2, cp);
  235.             *cp = '\0';
  236.         }
  237. #endif
  238.     } else {
  239.         sysfile2 = Myname;
  240.         strcpy(file2, argv[argc - 1]);
  241.     }
  242.  
  243.     /*
  244.      * if there are more than 2 argc, file2 is a directory
  245.      */
  246.     if (argc > 3)
  247.         strcat(file2, "/");
  248.  
  249.     /*
  250.      * system names limited to SYSNSIZE(6) chars
  251.      */
  252.     if (strlen(sysfile2) > SYSNSIZE)
  253.         *(sysfile2 + SYSNSIZE) = '\0';
  254.  
  255.  
  256. #ifdef FOWARD
  257.     strncpy(sys2save, sysfile2, SYSNSIZE);
  258. #endif
  259.     /*
  260.      * do each from argument
  261.      */
  262.     getseq(sqn);
  263.     while (argc > 2) {
  264.         if ((cp = strchr(argv[1], '!')) != NULL) {
  265.             sysfile1 = argv[1];
  266.             *cp = '\0';
  267.             if (strlen(sysfile1) > SYSNSIZE)
  268.                 *(sysfile1 + SYSNSIZE) = '\0';
  269.             if (*sysfile1 == '\0')
  270.                 sysfile1 = Myname;
  271.             else
  272.                 sprintf(Rmtname, "%.6s", sysfile1);
  273.             if (versys(sysfile1) != 0) {
  274.                 fprintf(stderr, "bad system name: %s\n", sysfile1);
  275.                 cleanup(-6);
  276.             }
  277.             strcpy(file1, cp + 1);
  278. #ifdef FOWARD
  279.             /*
  280.              * if forwarding for a file to receive 
  281.              * then simulate a remote
  282.              * xuucp by prepending reverse order of
  283.              * of forwarding route to file and xeq uucp on
  284.              * remote site 
  285.              */
  286.             if (strchr(file1,'!') != NULL)    
  287.                 {
  288.                 register char *i;
  289.                 if (chkpub(file1)==FAIL) {
  290.                     fprintf(stderr,"\n Forwarding from nonpublic directories denied - uucp failed\n");
  291.                     cleanup(-7);
  292.                 }
  293.                 dlogent("sysfile2", sysfile2);
  294.                 if (strncmp(sysfile2, Myname, SYSNSIZE) == SAME) {
  295.  
  296.             /*
  297.              * due to remote fwding mechanism file must
  298.              * return to public directory
  299.              */
  300.                     if (chkpub(file2)==FAIL) {
  301.                     fprintf(stderr,"file must be returned to a public spool directory - uucp failed\n");
  302.                     cleanup(-8);
  303.                     }
  304.                 }
  305.                 else 
  306.                 if (chkpub(file2) == FAIL) {
  307.                     fprintf(stderr,"\nforwarding to nonpublic directory not permitted - uucp failed\n");
  308.                     cleanup(-9);
  309.                 }
  310.  
  311.                 /*
  312.                  * execute uux
  313.                  * remote uucp
  314.                  */
  315.                 if (Ename[0] != '\0') {
  316.                     xuux(Ename, sysfile1, file1, sysfile2, file2, "");
  317.                     --argc;
  318.                     argv++;
  319.                     continue;
  320.                 }
  321.                 /*
  322.                  * Form reverse order of fowarding sites
  323.                  */
  324.                 *tsys2 = '\0';
  325.                 strcpy(tfile1, file1);
  326.                 /*
  327.                  * Strip off destination file
  328.                  */
  329.                 i = strrchr(tfile1, '!');
  330.                 *i = '\0';
  331.                 /*
  332.                  * Strip off last site
  333.                  */
  334.                 if ((i=strrchr(tfile1, '!')) != NULL){
  335.                     *i = '\0';
  336.                     /*
  337.                      * Get next site
  338.                      */
  339.                     while ((i=strrchr(tfile1,'!')) != NULL){
  340.                         strncat(tsys2, i+1, SYSNSIZE);
  341.                         strcat(tsys2, "!");
  342.                         *i = '\0';
  343.                     }
  344.                     strcat(tsys2, tfile1);
  345.                     strcat(tsys2, "!");
  346.                 }
  347.                 strncat(tsys2, sysfile1, SYSNSIZE);
  348.                 strcat(tsys2, "!");
  349.                 strcat(tsys2, Myname);
  350.                 if (strncmp(sys2save, Myname, SYSNSIZE) != SAME) {
  351.                     strcat(tsys2, "!");
  352.                     dlogent(sys2save, "sys2save");
  353.                     strcat(tsys2, sys2save);
  354.                 }
  355.                 sysfile2 = tsys2;
  356.                 dlogent(sysfile2,"reverse sysfile2");
  357.             }else 
  358.                 if ((strncmp(sysfile1, Myname, SYSNSIZE) != SAME) &&
  359.                     (strncmp(sysfile2, Myname, SYSNSIZE) != SAME))
  360.                 /*
  361.                  * both sites are remote - no forwarding
  362.                  * to source file
  363.                  */
  364.  
  365.                 {
  366.                 if (Ename[0] != '\0')  {
  367.                     xuux(Ename, sysfile1, file1, sysfile2,
  368.                         file2, "");
  369.                     --argc;
  370.                     argv++;
  371.                     continue;
  372.                 }
  373.                 if (chkpub(file2) == FAIL) {
  374.                     fprintf(stderr,"\nuse -e option for remote transfer to nonpublic directories\n");
  375.                     cleanup(-10);
  376.                 }
  377.                 sprintf(tsys2, "%s!%s", Myname, sys2save);
  378.                 strcpy(sysfile2, tsys2);
  379.                 dlogent(sysfile2, "reverse sys2 -no fowarding");
  380.                 }
  381.             /*
  382.              *  If fowarding then prepend ! to fowarding string
  383.              */
  384.             if (strchr(file1, '!') != NULL)    {
  385.                 *cp = '!';
  386.                 strcpy(file1, cp);
  387.                 *cp = '\0';
  388.             }
  389.             if ((strncmp(sysfile1, Myname, SYSNSIZE) != SAME) && (file2[0] == '!')){
  390.                 /*
  391.                  *    remove leading ! from file2 so that
  392.                  *    copy case 3 will not produce !!
  393.                  */
  394.                 strcpy(tfile1, &file2[1]);
  395.                 strcpy(file2, tfile1);
  396.             }
  397. #endif
  398.         } else {
  399.             sysfile1 = Myname;
  400.             strcpy(file1, argv[1]);
  401.         }
  402.         DEBUG(4, "file1 - %s\n", file1);
  403.         if  (copy(sysfile1, file1, sysfile2, file2))
  404.             errors++;
  405. #ifdef FOWARD
  406.         strcpy(sysfile2, sys2save);
  407. #endif
  408.         --argc;
  409.         argv++;
  410.     }
  411.  
  412.     clscfile();
  413.  
  414.     /*
  415.      * do not spawn daemon if -r option specified
  416.      */
  417.     limit = ulimit(1,dummy);
  418.     if (*Ropt != '-')
  419.         if (limit < CDLIMIT)  {
  420.             sprintf(msg,"ULIMIT (%ld) < CDLIMIT (%ld)",limit,
  421.                     CDLIMIT);
  422.             logent(User,msg);
  423.         }
  424.         else
  425.             xuucico(Rmtname);
  426.     cleanup(errors);
  427. }
  428.  
  429. /*
  430.  * cleanup lock files before exiting
  431.  */
  432. cleanup(code)
  433. register int code;
  434. {
  435.     void exit();
  436.  
  437.     logcls();
  438.     rmlock(CNULL);
  439.     if (code < 0)
  440.         fprintf(stderr, "uucp failed completely: code %d\n", code);
  441.     if (code > 0) {
  442.         fprintf(stderr, "uucp failed partially: %d error", code);
  443.         if (code==1) fprintf(stderr," \n");
  444.         else fprintf(stderr,"s \n");
  445.         }
  446.     exit(code);
  447. }
  448.  
  449.  
  450. /*
  451.  * generate copy files
  452.  * return:
  453.  *    0    -> success
  454.  *    FAIL    -> failure
  455.  */
  456. copy(s1, f1, s2, f2)
  457. char *s1, *f1, *s2, *f2;
  458. {
  459.     FILE *cfp, *gtcfile();
  460.     struct stat stbuf, stbuf1;
  461.     int type, statret;
  462.     char dfile[NAMESIZE];
  463.     char file1[MAXFULLNAME], file2[MAXFULLNAME];
  464.     char *strchr(), *strcat(), *strcpy();
  465.     char *strrcpy();
  466.     char opts[100];
  467.  
  468.     type = 0;
  469.     opts[0] = '\0';
  470.     strcpy(file1, f1);
  471.     strcpy(file2, f2);
  472.     if (strncmp(s1, Myname, SYSNSIZE) != SAME)
  473.         type = 1;
  474.     if (strncmp(s2, Myname, SYSNSIZE) != SAME)
  475.         type += 2;
  476.     if (type & 01)
  477.         if ((strchr(file1, '*') != NULL
  478.           || strchr(file1, '?') != NULL
  479.           || strchr(file1, '[') != NULL))
  480.             type = 4;
  481.  
  482.     switch (type) {
  483.     case 0:
  484.  
  485.         /*
  486.          * all work here
  487.          */
  488.         DEBUG(4, "all work here %d\n", type);
  489.  
  490.         /*
  491.          * check access control permissions
  492.          */
  493.         if (ckexpf(file1))
  494.              return(FAIL);
  495.         if (ckexpf(file2))
  496.              return(FAIL);
  497.         if (stat(file1, &stbuf) != 0) {
  498.             fprintf(stderr, "can't get file status %s \n copy failed\n",
  499.               file1);
  500.             return(2);
  501.         }
  502.         statret = stat(file2, &stbuf1);
  503.         if (statret == 0
  504.           && stbuf.st_ino == stbuf1.st_ino
  505.           && stbuf.st_dev == stbuf1.st_dev) {
  506.             fprintf(stderr, "%s %s - same file; can't copy\n", file1, file2);
  507.             return(3);
  508.         }
  509.         if (chkpth(User, "", file1) != 0
  510.           || chkperm(file2, strchr(Optns, 'd'))
  511.           || chkpth(User, "", file2) != 0) {
  512.             fprintf(stderr, "permission denied\n");
  513.             cleanup(1);
  514.         }
  515.         if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
  516.             fprintf(stderr, "directory name illegal - %s\n",
  517.               file1);
  518.             return(4);
  519.         }
  520.         if ((stbuf.st_mode & ANYREAD) == 0) {
  521.             fprintf(stderr, "can't read file (%s) mode (%o)\n",
  522.               file1, stbuf.st_mode);
  523.             return(5);
  524.         }
  525.         if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) {
  526.             fprintf(stderr, "can't write file (%s) mode (%o)\n",
  527.               file2, stbuf1.st_mode);
  528.             return(6);
  529.         }
  530.  
  531.         /*
  532.          * copy file locally
  533.          */
  534.         xcp(file1, file2);
  535.         chmod(file2, stbuf.st_mode | 0666);
  536.         logent("WORK HERE", "DONE");
  537.         return(0);
  538.     case 1:
  539.  
  540.         /*
  541.          * receive file
  542.          */
  543.         DEBUG(4, "receive file - %d\n", type);
  544.  
  545.         /*
  546.          * expand source and destination file names
  547.          * and check access permissions
  548.          */
  549.         if (file1[0] != '~')
  550.             if (ckexpf(file1))
  551.                  return(7);
  552.         if (ckexpf(file2))
  553.              return(8);
  554.         if (chkpth(User, "", file2) != 0) {
  555.             fprintf(stderr, "permission denied\n");
  556.             return(9);
  557.         }
  558.  
  559.             /*
  560.              * execute uux
  561.              * remote uucp
  562.              */
  563.         if (Ename[0] != '\0') {
  564.             xuux(Ename, s1, file1, s2, file2, opts);
  565.             return(0);
  566.         }
  567.  
  568.         /*
  569.          * insert JCL in file
  570.          */
  571.         cfp = gtcfile(s1);
  572.         fprintf(cfp, "R %s %s %s %s %s\n", file1, file2, User, Optns, Sfile);
  573.         break;
  574.     case 2:
  575.  
  576.         /*
  577.          * send file
  578.          */
  579.         if (ckexpf(file1))
  580.              return(10);
  581.         if (file2[0] != '~')
  582.             if (ckexpf(file2))
  583.                  return(11);
  584.         DEBUG(4, "send file - %d\n", type);
  585.  
  586.         if (chkpth(User, "", file1) != 0) {
  587.             fprintf(stderr, "permission denied %s\n", file1);
  588.             return(12);
  589.         }
  590.         if (stat(file1, &stbuf) != 0) {
  591.             fprintf(stderr, "can't get status for file %s\n", file1);
  592.             return(13);
  593.         }
  594.         if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
  595.             fprintf(stderr, "directory name illegal - %s\n",
  596.               file1);
  597.             return(14);
  598.         }
  599.         if ((stbuf.st_mode & ANYREAD) == 0) {
  600.             fprintf(stderr, "can't read file (%s) mode (%o)\n",
  601.               file1, stbuf.st_mode);
  602.             return(15);
  603.         }
  604.         if (notifopt && (strchr(Optns, 'n') == NULL))
  605.             strcat(Optns, "n");
  606.         /*
  607.          * execute uux
  608.          * remote uucp
  609.          */
  610.         if (Ename[0] != '\0') {
  611.             if(notifopt)
  612.                 sprintf(opts, "-n%s", Nuser);
  613.             xuux(Ename, s1, file1, s2, file2, opts);
  614.             return(0);
  615.         }
  616.  
  617.         /*
  618.          * make a copy of file in spool directory
  619.          */
  620.         if (Copy) {
  621.             updjb(); sprintf(dfile, "%c.%.6s%c%.1s%.4d", DATAPRE, s2, Grade, subjob, jobid); 
  622.             if (xcp(file1, dfile) != 0) {
  623.                 fprintf(stderr, "can't copy %s\n", file1);
  624.                 return(16);
  625.             }
  626.             chmod(dfile, DFILMODE);
  627.         } else {
  628.  
  629.             /*
  630.              * make a dummy D. name
  631.              * cntrl.c knows names < 6 chars are dummy D. files
  632.              */
  633.             strcpy(dfile, "D.0");
  634.         }
  635.  
  636.         /*
  637.          * insert JCL in file
  638.          */
  639.         cfp = gtcfile(s2);
  640.         fprintf(cfp, "S  %s %s %s %s %s %o %s %s\n", file1, file2,
  641.             User, Optns, dfile, stbuf.st_mode & 0777, Nuser, Sfile);
  642.         break;
  643.     case 3:
  644.     case 4:
  645.  
  646.         /*
  647.          * send uucp command for execution on s1
  648.          */
  649.         DEBUG(4, "send uucp command - %d\n", type);
  650.         if (strncmp(s2,  Myname, SYSNSIZE) == SAME) {
  651.             if (ckexpf(file2))
  652.                  return(17);
  653.             if (chkpth(User, "", file2) != 0) {
  654.                 fprintf(stderr, "permission denied\n");
  655.                 return(18);
  656.             }
  657.         }
  658.  
  659.             /*
  660.              * execute uux
  661.              * remote uucp
  662.              */
  663.         if (Ename[0] != '\0') {
  664.             xuux(Ename, s1, file1, s2, file2, opts);
  665.             return(0);
  666.         }
  667.  
  668.         /*
  669.          * insert JCL in file
  670.          */
  671.         cfp = gtcfile(s1);
  672.         fprintf(cfp, "X %s %s!%s %s %s %s\n", file1, s2, file2, User, Optns, Sfile);
  673.         break;
  674.     }
  675.     return(0);
  676. }
  677.  
  678. /*
  679.  * check security violations - forwarding to/from nonpublic directories
  680.  *    ckfile    -> src/dst path
  681.  *    return:    0 -> ok
  682.  *        FAIL -> not ok
  683.  */
  684. chkpub(ckfile)
  685. char *ckfile;
  686. {
  687.     char *s;
  688.     register char *i;
  689.     s = (i=strrchr(ckfile,'!'))?i+1:ckfile;
  690.  
  691.     /*
  692.      *    Ensure forwarding to/from public spool directory
  693.      */
  694.  
  695.     if (!prefix("~/",s) && !prefix(PUBDIR,s))
  696.         return(FAIL);
  697.     
  698.     /*
  699.      *    Detect illegal attempts to forward though (~/../) public dir.
  700.      */
  701.  
  702.     for (i = ++s; *i != '\0'; i++)
  703.         if (*i == '/' && prefix("/../", i))  
  704.             return(FAIL);
  705.     return(0);
  706. }
  707.                 
  708. /*
  709.  * execute uux for remote uucp
  710.  *    ename    -> remote system name to execute uucp on
  711.  *    s1    -> remote system name
  712.  *    f1    -> remote file name
  713.  *    s2    -> remote system name
  714.  *    f2    -> remote file name
  715.  *    opts    -> uucp options
  716.  * return:
  717.  *    none
  718.  */
  719. xuux(ename, s1, f1, s2, f2, opts)
  720. char *ename, *s1, *s2, *f1, *f2, *opts;
  721. {
  722.     char cmd[200];
  723.  
  724.     DEBUG(4, "Ropt(%s) ", Ropt);
  725.     DEBUG(4, "ename(%s) ", ename);
  726.     DEBUG(4, "s1(%s) ", s1);
  727.     DEBUG(4, "f1(%s) ", f1);
  728.     DEBUG(4, "s2(%s) ", s2);
  729.     DEBUG(4, "f2(%s)\n", f2);
  730. #ifdef FOWARD
  731.     if (*f2=='!') f2++;
  732. #endif
  733.     sprintf(cmd, "uux %s %s!uucp -C %s %s!%s \\(%s!%s\\)",
  734.      Ropt, ename, opts,  s1, f1, s2, f2);
  735.     DEBUG(4, "cmd (%s)\n", cmd);
  736.     system(cmd);
  737.     return;
  738. }
  739.  
  740. FILE *Cfp = NULL;
  741. char Cfile[NAMESIZE];
  742. #define NSYS    20
  743. struct presys{
  744.     char    pre_name[NAMESIZE];
  745.     char    pre_id[2];
  746.     char    pre_grade;
  747. }presys[NSYS];
  748. int    nsys    = 0;
  749. struct presys *csys();
  750.  
  751. /*
  752.  * get a Cfile descriptor
  753.  *    sys    -> system name
  754.  * return:
  755.  *    an open file descriptor
  756.  */
  757. FILE *
  758. gtcfile(sys)
  759. register char *sys;
  760. {
  761.     static int cmdcount = 0;
  762.     register int i;
  763.     struct presys *p;
  764.     extern int errno;
  765.     char *strcpy();
  766.  
  767.     /*
  768.      * a new c.file is generated each time a different 
  769.      * system is referenced
  770.      */
  771.     if((p = csys(sys, Grade)) == NULL){
  772.  
  773.         if(nsys != 0){
  774.             clscfile();
  775.         }
  776.         if(cmdcount == 0){
  777.             if(prjob == JOBON)
  778.                 fprintf(stdout,"uucp job %d\n", jobid);
  779.         }
  780.         updjb(); sprintf(Cfile, "%c.%.6s%c%.1s%.4d", CMDPRE, sys, Grade, subjob, jobid); 
  781.         cmdcount = 1;
  782.         Cfp = fopen(Cfile, "a+");
  783.         ASSERT(Cfp != NULL, "CAN'T OPEN", Cfile, 0);
  784.         insys(sys, subjob[0], Grade);
  785.     }else
  786.     if(strcmp(presys[nsys-1].pre_name, sys) != SAME){
  787.         clscfile();
  788.         sprintf(Cfile, "%c.%.6s%c%.1s%.4d", CMDPRE, sys, Grade, p->pre_id, jobid); 
  789.         Cfp = fopen(Cfile, "a+");
  790.         ASSERT(Cfp != NULL, "CAN'T OPEN", Cfile, 0);
  791.     }
  792.         return(Cfp);
  793. }
  794. struct presys *
  795. csys(p, g)
  796. register char *p, g;
  797. {
  798.     register int i;
  799.     static int jid = 0;
  800.  
  801.     if(jobid != jid){
  802.         jid = jobid;
  803.         nsys = 0;
  804.     }
  805.     for(i=0;i<nsys;i++){
  806.         if(strcmp(p,&presys[i].pre_name[0]) == SAME)
  807.             if(g == presys[i].pre_grade)
  808.                 return(&presys[i]);
  809.     }
  810.     return(NULL);
  811. }
  812.  
  813. insys(p, c, g)
  814. register char *p;
  815. char    c;
  816. {
  817.  
  818.     strcpy(presys[nsys].pre_name, p);
  819.     presys[nsys].pre_grade = g;
  820.     presys[nsys++].pre_id[0] = c;
  821. }
  822.  
  823. /*
  824.  * close cfile
  825.  * return:
  826.  *    none
  827.  */
  828. clscfile()
  829. {
  830.     if (Cfp == NULL)
  831.         return;
  832.     fclose(Cfp);
  833. /*
  834.     chmod(Cfile, ~WFMASK & 0777);
  835. */
  836.     logent(Cfile, "QUE'D");
  837.     US_CRS(Cfile);
  838.     Cfp = NULL;
  839.     return;
  840. }
  841.